#include"../include/file_descriptor.h"
#include"../include/block.h"
#include"../include/main_header.h"
#include"../include/hashtab.h"
#include"../include/free_list.h"
#include"../include/narray.h"
#include"../include/bst.h"
#include"../include/trie.h"
#include"../include/vfs_errorcodes.h"
#include<string.h>
#include<stdio.h>
#include<malloc.h>

void initailizeFDList()
{
	FDList = (struct file_descriptor_list*) malloc(sizeof(struct file_descriptor_list));
	strcpy(FDList -> fdescriptor.file_name, "Sentinel");
	FDList -> fpath[0] = '\0';
	FDList -> next = NULL;
	FDList -> prev = NULL;
}
void insertFD (struct file_descriptor fd, char path[])
{
	//printf("%s\n", "ok");
	struct file_descriptor_list *temp, *ptr;
	temp = (struct file_descriptor_list*) malloc(sizeof(struct file_descriptor_list));
	temp -> fdescriptor = fd;
	strcpy(temp -> fpath, path);
	if(FDList == NULL)
	{
		FDList = temp;
		FDList -> next = NULL;
		FDList -> prev = NULL;
	}

	else if(FDList -> next == NULL)
	{
		FDList -> next = temp;
		temp -> prev = FDList;
		temp -> next = NULL;
	}

	else
	{	
		FDList -> next -> prev = temp;
		temp -> next = FDList -> next;
		temp -> prev = FDList;
		FDList -> next = temp;
	}
}


struct file_descriptor* getRecentFDinserted (struct file_descriptor_list* FDList)
{
	return &(FDList -> next->fdescriptor) ;
}

void traverseFDList()
{
	printf("\n%s\n", "----------------traverseFDList-------------------");
	struct file_descriptor_list* temp;
	temp = FDList;
	while (temp != NULL)
	{
		printf("\nfile name: %s\nfile path: %s\n", temp -> fdescriptor.file_name, temp -> fpath);
		printf("descriptors address:%ld\n",temp -> fdescriptor.descriptor_address);
		printf("descriptors:%d\n",temp -> fdescriptor.dir_descriptors);		
		temp = temp -> next;
	}
}

void make_dir_rec(char *path, char *name)
{
	int j;
	char temppath[100];
    char **intmpath;
    int nlev;
    nlev = countlevel(path);
    intmpath = (char**) malloc (sizeof(char*) * nlev);
    for(j=0; j<=nlev; j++)
    	intmpath[j] = (char*) malloc (sizeof(char) * 100);
    struct node *result;
    int i=0;
    strcpy(temppath, path);
    result= Searchnarray(temppath);
    while(result==NULL)
        {
            result=Searchnarray(temppath);
            if(result==NULL)
                {
                    strcpy(intmpath[i],temppath);
                    i++;
                }
            strcpy(temppath, Findparentpath(temppath));
            if(!strcmp(temppath,""))
            	result=Searchnarray("/");
        }

    for(i--;i>=0; i--)
        {
            //prin: %s \n",  intmpath[i]);
           // printf("\n mkdir call to be generated for parent Path = %s and ",Findparentpath(intmpath[i]) );
           // printf("foldername = %s \n ", foldernamefrompath(intmpath[i]));
        	make_dir(Findparentpath(intmpath[i]),foldernamefrompath(intmpath[i]));

        }
    make_dir(path,name);

    //    printf("%s\n", "check1");

     //   display(root);

}


void make_dir(char *path,char*name)
{
	struct file_descriptor f;
	struct node *n;

	unsigned long int temp,current_block,block_address;
	int j,k=1;
	unsigned long int free_blocks;
	//make the file descriptor
	strcpy(f.file_name,name);
	strcpy(f.file_type,"dir");
	f.file_size=0;
	//free_blocks =	get_current_free_size();
	//printf ("free blocks are -----------%ld" ,free_blocks);
	if( get_current_free_size() <= 1)
	{
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_01);
		return;
	}
	f.start_block_address=get_free_block_new();
	f.dir_descriptors=0;
//	display(root);

	if(Searchnarray(path)==NULL)
	{

		make_dir_rec(path, name);
	//	printf("%s\n", "check2");
		return;
	}

	if(strlen(path)>1)
	{
				
		n=Searchnarray(path);
		
		//printf("\nparent desc: %d",n->nodefile_descriptor->dir_descriptors);
		//printf("\nbefore incrementing----------%d\n", n->nodefile_descriptor->dir_descriptors);
		n->nodefile_descriptor->dir_descriptors++;
		//printf("\nafter incrementing----------%d\n", n->nodefile_descriptor->dir_descriptors);
		//printf("\npath:%s name:%s",path,n->nodefile_descriptor->file_name);		
		//printf("\nparent desc: %d",n->nodefile_descriptor->dir_descriptors);
		//printf("\naddress:%u",(n->nodefile_descriptor));
		//display(root);		
		n=Searchnarray(path);
		//printf("\nafter traversing again descriptos--------%d\n", n->nodefile_descriptor->dir_descriptors);
		//traverseFDList();

		block_address=absoluteToblock(n->nodefile_descriptor->start_block_address);

		while(fl.list[block_address]!=0xFFFF)
		{
			block_address=fl.list[block_address];
			k++;
		}

		if(k*BLOCK_DESCRIPTORS == (n->nodefile_descriptor->dir_descriptors-1))
		{
			if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_01);
				return;
			}
			temp = get_free_block_new();
			temp = absoluteToblock(temp);
			fl.list[block_address]=temp;
			temp = blockToabsolute(temp);
		}

		else
		{
			j =(n->nodefile_descriptor->dir_descriptors-1)-(k-1)*BLOCK_DESCRIPTORS;
			temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

		}


	}

	else
	{

		//n=searchnarray(path);

		//n->nodefile_descriptor->dir_descriptors++;
	
		block_address=0;

		while(fl.list[block_address]!=0xFFFF)
		{
			block_address=fl.list[block_address];
			k++;
		}

		if(k*BLOCK_DESCRIPTORS == m.root_descriptors)
		{
			if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_01);
				return;
			}
			temp = get_free_block_new();//absolute address
			temp = absoluteToblock(temp);
			fl.list[block_address]=temp;
			temp = blockToabsolute(temp);
		}

		else
		{
			j =(m.root_descriptors)-(k-1)*BLOCK_DESCRIPTORS;
			temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

		}
		m.root_descriptors++;
//		display(root);
	}


	f.descriptor_address=temp;

	
	insertFD(f,path);
	
	narrayinsert(path, getRecentFDinserted(FDList));
	insertFileInHashTable(getRecentFDinserted(FDList), path, hashTable);
	avl_root = insert_into_BST(getRecentFDinserted(FDList), path);
//	printf("\ndirectory %s in path:%s created\n",name,path);

	//display(root);
}

unsigned long int make_dir_dummy(char *path)
{
	struct file_descriptor f;
	struct node *n;

	unsigned long int temp,current_block,block_address;
	int j=0,k=1;
	//make the file descriptor
	
//	display(root);


	if(strlen(path)>1)
	{
				
		n=Searchnarray(path);
		
		//printf("\nparent desc: %d",n->nodefile_descriptor->dir_descriptors);
		n->nodefile_descriptor->dir_descriptors++;
		//printf("\npath:%s name:%s",path,n->nodefile_descriptor->file_name);		
		//printf("\nparent desc: %d",n->nodefile_descriptor->dir_descriptors);
		//printf("\naddress:%u",(n->nodefile_descriptor));
		//display(root);		
		
		block_address=absoluteToblock(n->nodefile_descriptor->start_block_address);
		//printf("\n block address %ld",block_address);
		while(fl.list[block_address]!=0xFFFF)
		{
			block_address=fl.list[block_address];
			k++;
		}
		
		if(k*BLOCK_DESCRIPTORS == (n->nodefile_descriptor->dir_descriptors-1))
		{
			/*if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_01);
				return;
			}*/
			temp = get_free_block_new();
			temp = absoluteToblock(temp);
			fl.list[block_address]=temp;
			temp = blockToabsolute(temp);
		}
		
		else
		{
		//	printf("\nj is :%d\nk is : %d\n descrip : %d",j,k,n->nodefile_descriptor->dir_descriptors);
			j =(n->nodefile_descriptor->dir_descriptors-1)-(k-1)*BLOCK_DESCRIPTORS;
			temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);
		//	printf("\nj is :%d\n",j);
		}
		

	}

	else
	{

		//n=searchnarray(path);

		//n->nodefile_descriptor->dir_descriptors++;
	
		block_address=0;

		while(fl.list[block_address]!=0xFFFF)
		{
			block_address=fl.list[block_address];
			k++;
		}

		if(k*BLOCK_DESCRIPTORS == m.root_descriptors)
		{
			/*if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_01);
				return;
			}*/
			temp = get_free_block_new();//absolute address
			temp = absoluteToblock(temp);
			fl.list[block_address]=temp;
			temp = blockToabsolute(temp);
		}

		else
		{
			j =(m.root_descriptors)-(k-1)*BLOCK_DESCRIPTORS;
			temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

		}
		m.root_descriptors++;
//		display(root);
	}


	return temp;

	
	

}

void add_file(char *vfs_path,char *name,char *file_path)
        {
        struct file_descriptor f,fptr;
        struct block b;
        struct node *n;
        int i,j,k=1, flag = 0, x=0, y=0, namesize=0, typesize=0;
        char ch, *nametok, *typetok;
        unsigned long int block_address, current_block,temp;
        //make file descriptor
 	    for(i=strlen(name)-1; i>=0; i--)
        {
        	ch = name[i];
        	if(ch == '.')
        	{
        		flag = 1;
        		continue;
        	}
        	if(flag == 1)
        		namesize++;
        	else if(flag == 0)
        		typesize++;
        }	

        flag = 0;
        nametok = (char*) malloc (sizeof(char) * namesize);
        typetok = (char*) malloc (sizeof(char) * typesize);

        for(i=strlen(name)-1; i>=0; i--)
        {
        	ch = name[i];
        	if(ch == '.')
        	{
        		flag = 1;
        		continue;
        	}
        	if(flag == 1)
        		nametok[x++] = ch;
        	else if(flag == 0)
        		typetok[y++] = ch;
        }	
        strcat(nametok, "");
        strcat(typetok, "");

    /*    for(i=strlen(nametok)-1, x=0; i>=0, x<strlen(nametok); i--, x++)
        	f.file_name[x] = nametok[i];
        strcat(f.file_name, "");
*/
        for(i=strlen(typetok)-1, x=0; i>=0, x<strlen(typetok); i--, x++)
        	f.file_type[x] = typetok[i];
        strcat(f.file_type, "");

        if(flag == 0)
        {
        	strcpy(f.file_name, f.file_type);
        	strcpy(f.file_type, "");
        }
        strcpy(f.file_name,name);

    //    printf("-----------------%s\n", f.file_name);
    //    printf("-----------------%s\n", f.file_type);
		
        
    //    strcpy(f.file_type,"txt");
        //f.file_size=strlen(content);
        if( get_current_free_size() <= 1)
		{
			printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_04);
			return;
		}
        f.start_block_address=get_free_block_new();
	//printf("\nfile data startin at %ld\n",f.start_block_address);;
        f.dir_descriptors=0;


        if(strlen(vfs_path)>1)
        {
		n=Searchnarray(vfs_path);

	//	printf("\nparent descriptors before increment in add file %d\n",n->nodefile_descriptor->dir_descriptors);
		//traverseFDList();
		//display(root);
	//	printf("\nparent is %s\n",n->nodefile_descriptor->file_name);
		n->nodefile_descriptor->dir_descriptors++;
	//	printf("\nparent descriptors after increment in add file %d\n",n->nodefile_descriptor->dir_descriptors);
		//traverseFDList();
		//display(root);
		block_address=absoluteToblock(n->nodefile_descriptor->start_block_address);

			while(fl.list[block_address]!=0xFFFF)
			{
				block_address=fl.list[block_address];
				k++;
			}

			if(k*BLOCK_DESCRIPTORS == (n->nodefile_descriptor->dir_descriptors-1))
			{
				if( get_current_free_size() <= 1)
				{
					printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_04);
					return;
				}
				temp = get_free_block_new();
				temp = absoluteToblock(temp);
				fl.list[block_address]=temp;
				temp = blockToabsolute(temp);

			}

			else
			{
				j =(n->nodefile_descriptor->dir_descriptors-1)-(k-1)*BLOCK_DESCRIPTORS;
				temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

			}
        }

        else
        {

		
		//n->nodefile_descriptor->dir_descriptors++;

		block_address=0;

			while(fl.list[block_address]!=0xFFFF)
			{
				block_address=fl.list[block_address];
				k++;
			}

			if(k*BLOCK_DESCRIPTORS == m.root_descriptors)
			{
				if( get_current_free_size() <= 1)
				{
					printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_04);
					return;
				}
				temp = get_free_block_new();
				temp = absoluteToblock(temp);
				fl.list[block_address]=temp;
				temp = blockToabsolute(temp);

			}

			else
			{
				j =(m.root_descriptors)-(k-1)*BLOCK_DESCRIPTORS;
				temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

			}
			m.root_descriptors++;

        }

    //    printf("\naddress generated  in add file: %ld\n",temp );
        f.descriptor_address=temp;
	//printf("\nbefore writing data");
	f.file_size=write_data_multiple_blocks(file_path,f.start_block_address);
//	printf("\nafter writing data");

	insertFD(f,vfs_path);
    
    narrayinsert(vfs_path, getRecentFDinserted(FDList));
	
	insertFileInHashTable(getRecentFDinserted(FDList), vfs_path, hashTable);
	
	
	
	avl_root = insert_into_BST(getRecentFDinserted(FDList), vfs_path);
      //write_data(file_path,f.start_block_address);
	
 //	printf("\nfile %s addedd to the path using add_file: %s parent descriptors : %d",name,vfs_path,n->nodefile_descriptor->dir_descriptors);       
   //     exit(0); 
}
void write_data(char *file_path,unsigned long int address)
{
	char ch;
    FILE *fp_temp;
    fp_temp=fopen(file_path,"rb");
    fseek(fp,address,0);
    while(!feof(fp_temp))
    {
        fread(&ch,sizeof(char),1,fp_temp);
        fwrite(&ch,sizeof(char),1,fp);
    }
//    printf("%s\n", "data written sucessfully");
	fclose(fp_temp);          //glibc
    read_data(address);

}
unsigned long int write_data_multiple_blocks(char *file_path,unsigned long int address)
{
	char ch;
	unsigned long int size = 0;
	int k=1, ret;
    unsigned long int temp;
	FILE *fp_temp;
    	fp_temp=fopen(file_path,"rb");
	fseek(fp,address,0);
//	printf("\ndata writing at : %ld\n", address);
  	while(!feof(fp_temp))
    	{
        	fread(&ch,sizeof(char),1,fp_temp);
        	//printf("%c\n", ch);
        	ret = fwrite(&ch,sizeof(char),1,fp);
        	if(ret == 0)
        	{
				printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_05);
				return;
        	}

		size++;
		if(size == (BLOCK_SIZE-4)*k)
		{
			//printf("\nallocating new blocks in writing data \n");
			if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_04);
				return;
			}
			temp = get_free_block_new();
			temp = absoluteToblock(temp);
        	fl.list[absoluteToblock(address)]=temp;
			temp = blockToabsolute(temp);
			address = temp;
			fseek(fp,temp,0);
			k++;
		}
		
    	}
//	printf("\nfile size is %ld\n",size);
//    printf("%s\n", "data written sucessfully");
	fclose(fp_temp);          //glibc
    	//read_data(address);
	return size;
}

void update_file(char *vfs_path, char *file_path)
{

	
	//printf("\n---------------------file name is :%s",Findparentpath(vfs_path));
	char parent_path[100],name[20];
	strcpy(parent_path,Findparentpath(vfs_path));
	strcpy(name,foldernamefrompath(vfs_path));

//	printf("----------------------------------\n path: %s \n name : %s\n",parent_path,name);
	remove_file(vfs_path);
//	traverseFDList();

//	printf("----------after remove file----------");
//	display_blocks_info();
	add_file(parent_path,name,file_path);
//	printf("----------after add file ----------");
//	display_blocks_info();
}

void read_data(unsigned long int address)
{
	int i=0;
	char abc;
	fseek(fp, address, 0);
	while(i<10)
	{
		fread(&abc, sizeof(char), 1, fp);
//		printf("%c", abc);
		i++;
	}	
}

void fileout(char *vfspath,char *diskpath, int flag)
{
	struct node *n;
	n = Searchnarray(vfspath);
	unsigned long int start;
	int i=0,count=0,size=n->nodefile_descriptor->file_size;
	struct block b;
	FILE *ptr;
	
//	printf("\nfile size:%d",size);
	ptr = fopen(diskpath,"wb");
	if(!ptr)
	{
		printf("\nfile cant be opened\n");
		if(flag == 0)
		{
			printf("%s%s\n", "listfile_FAILURE ", ERR_VFS_LISTFILE_03);
			return;
		}
		else if(flag == 1)
		{
			printf("%s%s\n", "exportfile_FAILURE ", ERR_VFS_EXPORTFILE_02);
			return;
		}
	}
	start = absoluteToblock(n->nodefile_descriptor->start_block_address);			
	while(fl.list[start]!=0xFFFF)
	{
	
		fseek(fp,blockToabsolute(start),0);
		fread(&b,sizeof(struct block),1,fp);
				
		for(i=0;i<(BLOCK_SIZE-4);i++)
		{
			fwrite(&b.data[i],sizeof(char ),1,ptr);		
			//fprintf(ptr,"%c",b.data[i]);			
			//printf("%c",b.data[i]);
			count++;	
		}	
		
		//printf("%s",b.data);
		start = fl.list[start];
	}
	
	fseek(fp,blockToabsolute(start),0);
	fread(&b,sizeof(struct block),1,fp);
	for(i=0;(i<(BLOCK_SIZE-4) && (count<size));i++)
	{	
		fwrite(&b.data[i],sizeof(char ),1,ptr);
		//fprintf(ptr,"%c",b.data[i]);
//		printf("%c",b.data[i]);
		count++;	
	}		
	
//printf("export size%d\n",count );
//fclose(ptr);          //glibc
//printf("\nfile exported successfully to %s\n",diskpath);
	if(flag == 0)
		printf("%s\n", "listfile_SUCCESS");
	else if (flag == 1)
		printf("%s\n", "exportfile_SUCCESS");
}

void copy_file(char *src,char *dest, char *name)
{
	struct node *n;
	//printf("\ncopy fn called");
	
	n=Searchnarray(src);
	//printf("\nparent identified");	
	
	addfile_cpy(dest,n->nodefile_descriptor, name);
	

//	printf("\nfile coppied from %s to %s ",src,dest);

}

void addfile_cpy(char *vfs_path,struct file_descriptor *fd, char *name)
        {
        struct file_descriptor f,fptr;
        struct block b;
        struct node *n;
        int j,k=1;
        unsigned long int block_address, current_block,temp;
        //make file descriptor
        strcpy(f.file_name,name);
        strcpy(f.file_type,"txt");
        //f.file_size=strlen(content);
        if( get_current_free_size() <= 1)
		{
			printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_04);
			return;
		}
        f.start_block_address=get_free_block_new();
	//printf("\nfile data startin at %ld\n",f.start_block_address);;
        f.dir_descriptors=0;


        if(strlen(vfs_path)>1)
        {
		n=Searchnarray(vfs_path);

		n->nodefile_descriptor->dir_descriptors++;

		block_address=absoluteToblock(n->nodefile_descriptor->start_block_address);

		while(fl.list[block_address]!=0xFFFF)
		{
			block_address=fl.list[block_address];
			k++;
		}

		if(k*BLOCK_DESCRIPTORS == (n->nodefile_descriptor->dir_descriptors-1))
		{
			if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_04);
				return;
			}
			temp = get_free_block_new();
			temp = absoluteToblock(temp);
			fl.list[block_address]=temp;
			temp = blockToabsolute(temp);

		}

		else
		{
			j =(n->nodefile_descriptor->dir_descriptors-1)-(k-1)*BLOCK_DESCRIPTORS;
			temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

		}
        }

        else
        {

		//n=searchnarray(path);

		//n->nodefile_descriptor->dir_descriptors++;

		block_address=0;

		while(fl.list[block_address]!=0xFFFF)
		{
			block_address=fl.list[block_address];
			k++;
		}

		if(k*BLOCK_DESCRIPTORS == m.root_descriptors)
		{
			if( get_current_free_size() <= 1)
			{
				printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_04);
				return;
			}
			temp = get_free_block_new();
			temp = absoluteToblock(temp);
			fl.list[block_address]=temp;
			temp = blockToabsolute(temp);

		}

		else
		{
			j =(m.root_descriptors)-(k-1)*BLOCK_DESCRIPTORS;
			temp=blockToabsolute(block_address) + j*sizeof(struct file_descriptor);

		}
		m.root_descriptors++;

        }


        f.descriptor_address=temp;
	f.file_size=fd->file_size;
	
	write_cpy(f.start_block_address,fd);
	insertFD(f,vfs_path);
        narrayinsert(vfs_path, getRecentFDinserted(FDList));
	insertFileInHashTable(getRecentFDinserted(FDList), vfs_path, hashTable);
   	avl_root = insert_into_BST(getRecentFDinserted(FDList), vfs_path);
        //write_data(file_path,f.start_block_address);
	
        
        }
void write_cpy(unsigned long int start_dest,struct file_descriptor *fd)
{
	unsigned long int start;
	unsigned long int temp;
	struct block b;
	start = absoluteToblock(fd->start_block_address);
	start_dest = absoluteToblock(start_dest);
	//printf("new block:%ld",start_dest);		
	while(fl.list[start]!=0xFFFF)
	{
	
		fseek(fp,blockToabsolute(start),0);
		fread(&b,sizeof(struct block),1,fp);
		
		//printf("%s",b.data);
		fseek(fp,blockToabsolute(start_dest),0);
		fwrite(&b,sizeof(struct block),1,fp);	

		if( get_current_free_size() <= 1)
		{
			printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_04);
			return;
		}
		temp = get_free_block_new();
		temp = absoluteToblock(temp);
        	fl.list[start_dest]=temp;
		//temp = blockToabsolute(temp);
		start_dest = temp;
		
		//printf("new block:%ld",start_dest);			
		start = fl.list[start];
	}
	
	fseek(fp,blockToabsolute(start),0);
	fread(&b,sizeof(struct block),1,fp);
	//printf("%s",b.data);
	fseek(fp,blockToabsolute(start_dest),0);
	fwrite(&b,sizeof(struct block),1,fp);	

	//printf("new block:%ld",start_dest);


}

void remove_file(char *path)
{
	struct node *parent,*child;
	unsigned long int childblock;
	char p[120];
	
//	printf("\nreceived path hii:%s",path);

	child=Searchnarray(path);
//	printf("\n child value %s", child->nodefile_descriptor->file_name);
//	printf("\ndescriptor address:%ld",child->nodefile_descriptor->descriptor_address);
	
	/*while((*path)!='\0')
	{
		path++;	
	}
	while((*path)!='/')
	{
		path--;	
	}
	*path = '\0';
	path = p;
	printf("hiiii");
	printf("\nreceived path:%s\n",path);
	*/
	 //printf("\nreceived path:%s\n",Findparentpath(path));
	strcpy(p, Findparentpath(path));
	//printf("\nreceived p path:%s\n",p);	
//	display(root);

	parent = Searchnarray(p);
	//printf("\n parent value %s \n", parent->nodefile_descriptor->file_name);
	//printf("\n parent value %ld \n", parent->nodefile_descriptor->start_block_address);
//	printf("\n parent value %d \n", parent->nodefile_descriptor->dir_descriptors);
		
//update dir_descriptors by decrementing once
//	printf("\nbefore modifying descriptor-------------------\n");
	//traverseFDList();
	if(strlen(p)>1)
	{
		parent->nodefile_descriptor->dir_descriptors--;
	}
	else
	{
		m.root_descriptors--;
	}

//free the blocks coresponding to the file data
	childblock = absoluteToblock(child->nodefile_descriptor->start_block_address);	
	free_data_blocks(childblock);
//	printf("\n parent value %d \n", parent->nodefile_descriptor->dir_descriptors);
//fill the space create by the descriptor to be deleted
	//display_DS();
	//exit(0);
	fill_space(parent,child);
//remove the descriptor from all data structures
	deletenarray(path);
//	display(root);
//	printf("check 1\n");
	initailizeFDList();
//	traverseFDList();
//	display(root);
//	printf("check 2\n");
	//traverseFDList();
	repopulateFDlist2(root);
	mountnarray(FDList);	
	mountHashTable(FDList,hashTable);
//	mountTries(FDList, trieHead);
	mountBST(FDList);
//	printf("\nafter remove file and repopulation\n");
	//traverseFDList();
}


void move_file(char *source, char *dest, char *name)
{
//	printf("%s\n", "**************************************in move file");
	copy_file(source, dest, name);
	remove_file(source);
}


void move_dir(char *source,char *dest)
{	
	struct file_descriptor *f;	
	struct node *child, *parent,*moved;	
	char p[120];	
	unsigned long int temp;	
	int i;
//	printf("-----------before move dir-----------");	
//	traverseFDList();	
//	printf("\nfirst free : %ld\n",fl.first_free);
	/*for(i=0;i<10;i++)
	{
		printf("\nblocks:%ld",fl.list[i]);
	}*/

	child = Searchnarray(source);
	parent = Searchnarray(Findparentpath(source));

	if(strlen(Findparentpath(source))>1)
	{
		parent->nodefile_descriptor->dir_descriptors--;
	}
	else
	{
		m.root_descriptors--;
	}
		

	fill_space(parent,child);

	temp = make_dir_dummy(dest);

//	printf("\ntemp address is : ----------%ld\n",temp);
	movenode(source ,dest );
	//display(root);
	//exit(0);
	
	strcpy(p,dest);
	strcat(p,"/");
	strcat(p,foldernamefrompath(source));
	
	moved = Searchnarray(p);
	moved->nodefile_descriptor->descriptor_address = temp;
	
	initailizeFDList();

	repopulateFDlist2(root);
	mountnarray(FDList);
	mountHashTable(FDList,hashTable);
//	mountTries(FDList, trieHead);
	mountBST(FDList);
//	printf("-----------after move dir-----------");
//	traverseFDList();
	
//	printf("\nfirst free : %ld\n",fl.first_free);
/*	for(i=0;i<10;i++)
	{
		printf("\nblocks:%ld",fl.list[i]);
	}*/

	//display(root);

	//printf("%s\n", "movedir_SUCCESS");
}

//prototype in narray.h
void fill_space(struct node *parent,struct node *child)
{
	//printf("in fill space");	
	unsigned long int secondlastblock,lastblock,startblock;
	int *count,x=0;
	count = &x;
	struct node *latest;
	latest = parent;

//jump to the last block of the parent
	//printf("\nstart block:%ld",parent->nodefile_descriptor->start_block_address);
		if(strlen(parent->fullpath) > 1)
		{
			startblock = absoluteToblock(parent->nodefile_descriptor->start_block_address);
		}
		else
		{
			startblock = 0;
		}
//	printf("\nstart %ld\n",startblock);
	secondlastblock = get_secondlastblock(startblock);
	
//	printf("\nsecond last %ld\n",secondlastblock);	
	
	if(fl.list[secondlastblock]==0xFFFF)	
		lastblock = secondlastblock;	
	else
		lastblock = fl.list[secondlastblock];
	
//	printf("\nsecond last %ld and last %ld\n",secondlastblock,lastblock);
	secondlastblock = blockToabsolute(secondlastblock);	
	lastblock = blockToabsolute(lastblock);
//count the no. of descriptors in that block and also get the descriptor with highest address in that block
	/*
	count all the child which have (descriptor_address>=lastblock)
	and let the pointer *latest point to the descriptor which has the highest descriptor_address
	*/
//fill the empty space with the last descriptor fund by changing its descriptor address

//free the blocks if required
//	printf("in fill space");
//	printf("\nlast block:%ld\nsecond lasst block:%ld",lastblock,secondlastblock);
	latest = Deleteinfo(parent,count,lastblock);
//	printf("\ndescriptor address:%s",latest->nodefile_descriptor->file_name);
//	printf("\ncount is:%d",*count);
	if((*count==1) && (latest==child))
	{
		if (strlen(parent->fullpath) > 1)
		{
			if((parent->nodefile_descriptor->dir_descriptors)!=0)
			{		
				free_dir_blocks(absoluteToblock(secondlastblock));
			}
		}
		else
		{
			if(m.root_descriptors!=0)
			{		
				free_dir_blocks(absoluteToblock(secondlastblock));
			}
		}

	}
	else if((*count==1) && (latest!=child))
	{
		latest->nodefile_descriptor->descriptor_address = child->nodefile_descriptor->descriptor_address;
		free_dir_blocks(absoluteToblock(secondlastblock));
	}
	else if((*count>1) && (latest==child))
	{
		
	}
	else if((*count>1) && (latest!=child))
	{
		latest->nodefile_descriptor->descriptor_address = child->nodefile_descriptor->descriptor_address;
		
	}
	
//	printf("\ndescriptor address  after deletions:%ld",latest->nodefile_descriptor->descriptor_address);
	
}
void test()
{
	int i;
	unsigned long int a;
	struct file_descriptor_list *temp = FDList;
	//make_dir("/", "f1");
	//printf("\ndescr in LL%d",FDList->next->fdescriptor.dir_descriptors);
	//makedir("/f1", "f2");
	//printf("\ndescr in LL%d",FDList->next->next->fdescriptor.dir_descriptors);
	/*makedir("/f1", "f3");
	make_dir("/f1", "f4");
	make_dir("/f1", "f5");
	make_dir("/f1/f4", "f7");
	make_dir("/f1/f4", "f8");
	make_dir("/f1/f4", "f9");
	make_dir("/f1/f4", "f10");
	add_file("/","info","/home/yogesh/abc.txt");*/
	//add_file("/","informa","/home/yogesh/abc.txt");
	//add_file("/f1","yogesh","/home/yogesh/abc.txt");
	// while(temp != NULL)
	// {
	// 	print_descriptor(temp->fdescriptor);
	// 	temp = temp->next;
	// }
	/*printf("\nfirst free:%ld\n",fl.first_free);
	for(i=0; i<20; i++)
	{
		printf("%ld\n", fl.list[i]);
	}*/
	
	
//	addfile("/folder1", "testfile", "/home/sagar/Desktop/test.txt");
	traverseFDList();
	
	//display(root);
//	read_data(FDList->next->fdescriptor.start_block_address);
}

void print_narry(int current_dir_descriptors, char nary_path[])		//
{
	struct block b;
	struct file_descriptor f;
	unsigned long int temp_addr;
	char temp_path[100];
	int i=0,k=0;
	//rewind(fp);
	//printf("\n------------------------------------------\n");
	//fseek(fp,sizeof(struct main_header),0);
	fread(&b,sizeof(struct block),1,fp);
	fseek(fp,-sizeof(struct block),1);
	//printf("\nwhile path=%d",strlen(nary_path));
	while(b.next!=0xFFFF)
	{
				
		
		while(i<BLOCK_DESCRIPTORS)
		{	
			//printf("\npath:%s\n",nary_path);
			fread(&f,sizeof(struct file_descriptor),1,fp);
			//printf("\n%s\n",f.file_name);
			//printf("\n%s %d\n",f.file_type,f.dir_descriptors);

			insertFD(f, nary_path);		
		
			if(!strcmp(f.file_type,"dir"))
			{	strcpy(temp_path,nary_path);
				//printf("\nbefore if path=%d",strlen(nary_path));			
				if(strlen(nary_path)!=1)
				{			
					strcat(nary_path,"/");
				}			
				strcat(nary_path,f.file_name);
				temp_addr=ftell(fp);
				fseek(fp,f.start_block_address,0);		
				print_narry(f.dir_descriptors, nary_path);		//
				fseek(fp,temp_addr,0);
				strcpy(nary_path,temp_path);	
			}
			i++;
		}
		i=0;
		k=k+BLOCK_DESCRIPTORS;
		
		fseek(fp,b.next,0);
		fread(&b,sizeof(struct block),1,fp);
		fseek(fp,-sizeof(struct block),1);
	}
	
	
	while(k<current_dir_descriptors)
	{	
	//printf("\npath:%s\n",nary_path);
	fread(&f,sizeof(struct file_descriptor),1,fp);
	//printf("\n%s\n",f.file_name);

	insertFD(f, nary_path);
	
	k++;
		if(!strcmp(f.file_type,"dir"))
		{	
			strcpy(temp_path,nary_path);
			if(strlen(nary_path)!=1)
			{			
				strcat(nary_path,"/");
			}
			strcat(nary_path,f.file_name);
			temp_addr=ftell(fp);
			fseek(fp,f.start_block_address,0);		
			print_narry(f.dir_descriptors, nary_path);		//
			fseek(fp,temp_addr,0);	
			strcpy(nary_path,temp_path);
		}
	}
}


/*
void create_file(char *path,char *name,char *content)
{
	struct file_descriptor f,fptr;
	struct block b;
	int j,k;	
	unsigned long int current_block,temp;
//make file descriptor
	strcpy(f.file_name,name);
	strcpy(f.file_type,"txt");
	f.file_size=strlen(content);
	f.start_block_address=get_free_block();
	f.dir_descriptors=0;
	
	

//traverrse the path if file is not going to be stored in root dir  e.g. /folder1/folder2/file.txt
	if(strlen(path)>1)
	{
		fptr=traverse_path(path);
		
		fptr.dir_descriptors++;
		fseek(fp,fptr.descriptor_address,0);
		printf("\n%ld\n",ftell(fp));		
		fwrite(&fptr,sizeof(struct file_descriptor),1,fp);
		
		fseek(fp,fptr.start_block_address,0);
		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
		//printf("\n%ld     %d\n",ftell(fp),fptr.dir_descriptors);	
		//while(1);
		while(j<=(fptr.dir_descriptors-1))
		{
			fseek(fp,sizeof(struct file_descriptor),1);
			printf("\n%ld\n",ftell(fp));
			
			if(j==k*BLOCK_DESCRIPTORS && j<(fptr.dir_descriptors-1))
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			else if(j==k*BLOCK_DESCRIPTORS && j==(fptr.dir_descriptors-1))
			{
			temp = get_free_block();
			b.next= temp;
			fseek(fp,current_block,0);
			fwrite(&b,sizeof(struct block),1,fp);
			fseek(fp,temp,0);
			}
			j++;
			
		}		
	f.descriptor_address=ftell(fp);	
		
	}
//if the file is going to be stored in root directory	
	else
	{
	fseek(fp,sizeof(struct main_header),0); 
		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
			
		
		while(j<=m.root_descriptors)
		{
			fseek(fp,sizeof(struct file_descriptor),1);
			//printf("\n%ld\n",ftell(fp));
			
			if(j==k*BLOCK_DESCRIPTORS && j<m.root_descriptors)
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			else if(j==k*BLOCK_DESCRIPTORS && j==m.root_descriptors)
			{
			temp = get_free_block();
			b.next= temp;
			fseek(fp,current_block,0);
			fwrite(&b,sizeof(struct block),1,fp);
			fseek(fp,temp,0);
			}
			j++;
			
		}
	f.descriptor_address=ftell(fp);		
	m.root_descriptors++;
	//m.fd_used++;
	}
	
//write the file desccriptor 
	fwrite(&f,sizeof(struct file_descriptor),1,fp);

//take content in b.data	
	strcpy(b.data,content);

//store address FFFF showing end of file 	
	b.next=0xFFFF;	
	
//write the content of the file	
	fseek(fp,f.start_block_address,0);
	fwrite(&b,sizeof(struct block),1,fp);

//update meta header	
	update_main_header();
}

//to create directory
void make_dir_disk(char *path,char *name)
{
	struct file_descriptor f;
	struct file_descriptor fptr;
	struct block b;
	unsigned long int temp,current_block;
	int j,k;
//make the file descriptor
	strcpy(f.file_name,name);	
	strcpy(f.file_type,"dir");
	f.file_size=0;
	f.start_block_address=get_free_block();
	f.dir_descriptors=0;
	
	
			
	if(strlen(path)>1)
	{
		fptr=traverse_path(path);
				
		fptr.dir_descriptors++;
		
		fseek(fp,fptr.descriptor_address,0);
		//printf("\n%ld\n",ftell(fp));		
		fwrite(&fptr,sizeof(struct file_descriptor),1,fp);
		
		fseek(fp,fptr.start_block_address,0);
		//printf("\n%ld\n",ftell(fp));		
		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
		//printf("\n%ld     %d\n",ftell(fp),fptr.dir_descriptors);	
		//while(1);
		while(j<=(fptr.dir_descriptors-1))
		{
			fseek(fp,sizeof(struct file_descriptor),1);
			printf("\n%ld\n",ftell(fp));
			
			if(j==k*BLOCK_DESCRIPTORS && j<(fptr.dir_descriptors-1))
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			else if(j==k*BLOCK_DESCRIPTORS && j==(fptr.dir_descriptors-1))
			{
			temp = get_free_block();
			b.next= temp;
			fseek(fp,current_block,0);
			fwrite(&b,sizeof(struct block),1,fp);
			fseek(fp,temp,0);
			}
			j++;
			
		}		
	f.descriptor_address=ftell(fp);	
	}
	else
	{
		fseek(fp,sizeof(struct main_header),0);
		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
			
		
		while(j<=m.root_descriptors)
		{
			fseek(fp,sizeof(struct file_descriptor),1);
			//printf("\n%ld\n",ftell(fp));
			
			if(j==k*BLOCK_DESCRIPTORS && j<m.root_descriptors)
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			else if(j==k*BLOCK_DESCRIPTORS && j==m.root_descriptors)
			{
			temp = get_free_block();
			b.next= temp;
			fseek(fp,current_block,0);
			fwrite(&b,sizeof(struct block),1,fp);
			fseek(fp,temp,0);
			}
			j++;
			
		}
	f.descriptor_address=ftell(fp);		
	m.root_descriptors++;
	//m.fd_used++;
			
	}
		
	
	
	
	fwrite(&f,sizeof(struct file_descriptor),1,fp);
	
	b.next=0xFFFF;	
	fseek(fp,f.start_block_address,0);	
	fwrite(&b,sizeof(struct block),1,fp);	
	
	update_main_header();

}*/


struct file_descriptor traverse_path(char *path)
{
	long int temp;	
	int i=0,j=1,k=0;
	struct file_descriptor f;
	struct block b;
	//struct file_descriptor fptr;
	int current_dir_descriptors=m.root_descriptors;	
	char dir[10];
	rewind(fp);	
	fseek(fp,sizeof(struct main_header),0);
	path++;	
	while((*path)!='\0')
	{
		i=0;
		while((*path)!='/')
		{
			dir[i]=*path;
			path++;
			i++;			
		}		
		dir[i]='\0';
		path++;		
		j=1;	
		k=1;
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
		while(j<=current_dir_descriptors)
		{
			fread(&f,sizeof(struct file_descriptor),1,fp);
			//printf("\n%ld\n",ftell(fp));
			if(!strcmp(dir,f.file_name))
			{
				fseek(fp,f.start_block_address,0);
				current_dir_descriptors=f.dir_descriptors;
				break;
			}
			if(j==k*BLOCK_DESCRIPTORS && j<current_dir_descriptors)
			{
			fseek(fp,b.next,0);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			j++;
			
		}

	}
	
	//printf("%ld",ftell(fp));
	return f;
}
/*
void listdir(char *path)
{

struct file_descriptor f,fptr;
struct block b;
int current_dir_descriptors;
unsigned long int current_block;
int i,j,k;
if(strlen(path)>1)
	{
		fptr=traverse_path(path);
		current_dir_descriptors=fptr.dir_descriptors;
		printf("--------descriptor details-------------");			
		printf("\nname:%s",fptr.file_name);		
		printf("\naddress:%ld",fptr.start_block_address);
		printf("\ndir descriptors:%d",fptr.dir_descriptors);		
		//printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",fptr.file_size);
		printf("\ntype:%s",fptr.file_type);
		//printf("\nnext free:%ld",m.free_address);
		
		fseek(fp,fptr.start_block_address,0);
				
	}
	else
	{
	printf("--------it is a root directory-------------");
	fseek(fp,sizeof(struct main_header) ,0);	
	//fread(&m,sizeof(struct main_header),1,fp);
	current_dir_descriptors=m.root_descriptors;
	printf("\nroot descriptors:%d",current_dir_descriptors);
	}

		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
			
		
		while(j<=current_dir_descriptors)
		{
			//printf("%ld",ftell(fp);
			fread(&f,sizeof(struct file_descriptor),1,fp);
			print_descriptor(f);
			
			if(j==k*BLOCK_DESCRIPTORS && j<current_dir_descriptors)
			{
			fseek(fp,b.next,0);
			current_block=ftell(fp);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			
			j++;
			
		}	


}*/

/*
void print_descriptor(struct file_descriptor f)
{
printf("\n-----------------------------------------------------\n");			
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);		
		printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		printf("\nnext free:%ld",m.free_address);
		printf("\ndescriptor address:%ld",f.descriptor_address);
		printf("\nnew next free:%ld",fl.first_free);


}
void listfile(char *path, char *name)
{
struct file_descriptor f,fptr;
struct block b;
int current_dir_descriptors;
unsigned long int current_block;
int i,j,k;
if(strlen(path)>1)
	{
		fptr=traverse_path(path);
		current_dir_descriptors=fptr.dir_descriptors;
		fseek(fp,fptr.start_block_address,0);
				
	}
	else
	{
	
	fseek(fp,sizeof(struct main_header) ,0);	
	current_dir_descriptors=m.root_descriptors;
	printf("\nroot descriptors:%d",current_dir_descriptors);
	}

		j=1;	
		k=1;
		current_block=ftell(fp);
		fread(&b,sizeof(struct block),1,fp);	
		fseek(fp,-(sizeof(struct block)),1);	
			
		
		while(j<=current_dir_descriptors)
		{
			fread(&f,sizeof(struct file_descriptor),1,fp);
			//printf("\n%ld\n",ftell(fp));
			if(!strcmp(name,f.file_name))
			{
				
				break;
			}

			
			if(j==k*BLOCK_DESCRIPTORS && j<current_dir_descriptors)
			{
			fseek(fp,b.next,0);
			fread(&b,sizeof(struct block),1,fp);
			fseek(fp,-(sizeof(struct block)),1);			
			k++;
			}
			
			
			j++;
			
		}	

printf("\n-------file descriptor--------\n");
			
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);		
		printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		printf("\nnext free:%ld",m.free_address);
printf("---------------filedata-------------------");
fseek(fp,f.start_block_address,0);
fread(&b,sizeof(struct block),1,fp);
printf("\nfile data:%s\n",b.data);
}

*/











/////////////////////////////////////testing functions//////////////////////////////////////




void list_files()
{	
	//fp=fopen("test","rb+");
	int i;
	struct file_descriptor f;
	struct block b;	
	rewind(fp);	
	fseek(fp,sizeof(struct main_header),0);
	
	for(i=0;i<m.root_descriptors;i++)
	{
		fread(&f,sizeof(struct file_descriptor),1,fp);
		printf("-----------------------------------------------------");			
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);		
		printf("\nroot descriptors:%d",m.root_descriptors);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		printf("\nnext free:%ld",m.free_address);
		
	}
	//fclose(fp);
}
/*
struct file_descriptor f;
struct block b;
int i;
//fp=fopen("test","rb+");
rewind(fp);
fread(&m,sizeof(struct main_header),1,fp);
//printf("\nroot descriptors:%d",m.root_descriptors);
//traverse_path("/folder1/");
fseek(fp,380,0);
fread(&f,sizeof(struct file_descriptor),1,fp);
printf("-----------------------------------------------------");		
		//printf("\nfile %d:",i);		
		printf("\nname:%s",f.file_name);
		printf("\naddress:%ld",f.start_block_address);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		//printf("\nvfs_label:%ld",m.free_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);
		printf("\ndescriptor address:%ld",f.descriptor_address);
printf("-----------------------------------------------------");
*/
///////////////////////////////////////////////////////////////////////////////////////
/*fseek(fp,176+32,0);
fread(&f,sizeof(struct file_descriptor),1,fp);
printf("-----------------------------------------------------");		
		//printf("\nfile %d:",i);		
		printf("\nname:%s",f.file_name);		
		printf("\naddress:%ld",f.start_block_address);
		printf("\nsize:%ld",f.file_size);
		printf("\ntype:%s",f.file_type);
		//printf("\nvfs_label:%ld",m.free_address);
		printf("\ndir descriptors:%d",f.dir_descriptors);
		printf("\ndescriptor address:%ld",f.descriptor_address);
printf("-----------------------------------------------------");
*/
/*fseek(fp,40,0);
	for(i=1;i<15;i++)
	{

		fread(&b,sizeof(struct block),1,fp);
		printf("\naddress:%ld\n",b.next);		
	}
*/
//fclose(fp);
//}
// void file_content()
// {
// struct block b;
// //fp=fopen("test","rb+");
// /*
// fseek(fp,40,0);
// fread(&b,sizeof(struct block),1,fp);
// printf("\nfile 1:%s\n",b.data);
// */
// fseek(fp,552,0);
// fread(&b,sizeof(struct block),1,fp);
// printf("\nfile 1:%s\n",b.data);

// fseek(fp,1064,0);
// fread(&b,sizeof(struct block),1,fp);
// printf("\nfile 1:%s\n",b.data);

// fseek(fp,1576,0);
// fread(&b,sizeof(struct block),1,fp);
// printf("\nfile 1:%s\n",b.data);

// fseek(fp,4648,0);
// fread(&b,sizeof(struct block),1,fp);
// printf("\nfile 1:%s\n",b.data);

// //fclose(fp);

// }

void display_DS()
{
	display(root);
	traverseFDList();
	//display_blocks_info();
}
int make_dir_validate(char *pathv, char *namev)
{
	int success = 1;
	char temp[100];
	temp[0] = '\0';
	makeBSTpath(temp, pathv, namev);
//	printf("in make dir %s\n",temp );
	if(strlen(pathv) == 0 || strlen(namev) == 0)
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_00);
	}
	else if(*pathv != '/')
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", "Misc. error encountered");
	}
	else if(checkslash(namev) == -1)
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_02);
	}
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_05);
	}
	else if(searchBST(avl_root, temp, strlen(temp)) == 1)
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_03);
	}
	
	return success;
}

/*int list_dir_validate(char *vfspathv, int flagv ,char *filepathv)
{
	int success = 1;
	char temp[100];
	//makeBSTpath(temp, pathv, namev);
	if(strlen(vfspathv) == 0 || strlen(filepathv) == 0)
	{
		success = -1;
		printf("%s%s\n", "listdir_FAILURE ", ERR_VFS_LISTDIR_00);
	}
	
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_05);
	}
	/*else if(searchBST(avl_root, temp, strlen(temp)) == 1)
	{
		success = -1;
		printf("%s%s\n", "makedir_FAILURE ", ERR_VFS_MAKEDIR_03);
	}
	
	return success;
}*/

int delete_dir_validate(char *pathv)
{
	int success = 1;
	struct node* temp = NULL;
	
	if(strlen(pathv) == 0)
	{
		success = -1;
		printf("%s%s\n", "deletedir_FAILURE ", ERR_VFS_DELETEDIR_00);
	}
	
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "deletedir_FAILURE ", ERR_VFS_DELETEDIR_04);
	}
	else if(searchBST(avl_root, pathv, strlen(pathv)) == 0)
	{
		success = -1;
		printf("%s%s\n", "deletedir_FAILURE ", ERR_VFS_DELETEDIR_01);

	}
	else if(searchBST(avl_root, pathv, strlen(pathv)) == 1) 
		
	{	temp=Searchnarray(pathv);
		if(temp->left_child != NULL)
		{ 	success = -1;
			printf("%s%s\n", "deletedir_FAILURE ", ERR_VFS_DELETEDIR_02);
		}
	}

	return success;
}

int move_dir_validate(char *sourcev,char *destv)
{
	int success = 1;
	int i, j;
	struct node* temp = NULL;
	char temp_child[100];
	char temppath[100], name[20];
	temppath[0] = '\0';
	
	//node *temp;
	i=strlen(sourcev) - 1;
	while(sourcev[i] != '/')
		i--;
	i++;
	for(j=0; sourcev[i]!='\0'; i++, j++)
	{
		name[j] = sourcev[i];
	}

	name[j] = '\0';
	makeBSTpath(temppath, destv, name);
//	printf("temp path is%s\n",temppath );

	
	strcpy(temp_child,destv);
	i=strlen(temp_child) - 1;
	while(temp_child[i] != '/')
		i--;
	temp_child[i] = '\0';
	
	if((strlen(sourcev) == 0) || (strlen(destv) == 0))
	{
		success = -1;
		printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_00);
		return success;
	}
	
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_08);
		return success;
	}
	else if(searchBST(avl_root, sourcev, strlen(sourcev)) == 0)
	{
		success = -1;
		printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_01);
		return success;
	
	}
	else if(searchBST(avl_root, destv, strlen(destv)) == 0)
	{
		success = -1;
		printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_02);
		return success;
	}	
	else if(searchBST(avl_root, sourcev, strlen(sourcev)) == 1)
	{
		temp = Searchnarray(sourcev);
		if (strcmp(temp->nodefile_descriptor->file_type, "dir") != 0)
		{
			success = -1;
			printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_04);
			return success;
		}
	}
	

	if(searchBST(avl_root, temppath, strlen(temppath)) == 1)
	{
		success = -1;
		printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_05);
		return success;
	}
	else if(strcmp(sourcev,temp_child) == 0)
	{
		success = -1;
		printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_06);
	}
	else if(searchBST(avl_root, destv, strlen(destv)) == 1)
	{
		temp = Searchnarray(destv);
		if (strcmp(temp->nodefile_descriptor->file_type, "dir") != 0)
		{
			success = -1;
			printf("%s%s\n", "movedir_FAILURE ", ERR_VFS_MOVEDIR_07);
		return success;
		}
	}
	return success;
}

// #################################################### sagar's code begins ######################################################


//	copy two files with same name??
// copy file in root not happening. maybe because / not in bst.

int copy_file_validate(char *spath, char *dpath, char *name)
{
	
	int success = 1;
	struct node* temp = NULL;
	char tempp[100];
	tempp[0] = '\0';
	
	if(strlen(dpath)!=0 && strlen(name)!=0)
	{
		makeBSTpath(tempp, dpath, name);
	}
//	printf("\n%s\n", tempp);
//	printf("%s\n", dpath);
//	printf("%s\n", name);


	if(strlen(spath) == 0 || strlen(dpath) == 0)
	{
		success = -1;
		printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_00);
	}
	
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_05);
	}
	else if(searchBST(avl_root, spath, strlen(spath)) == 0)
	{
		success = -1;
		printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_01);

	}
	else if(searchBST(avl_root, dpath, strlen(dpath)) == 0)
	{
		success = -1;
		printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_02);

	}
	else if(searchBST(avl_root, tempp, strlen(tempp)) == 1)
	{
		success = -1;
		printf("%s%s\n", "copyfile_FAILURE ", "File with same name already exists");
	}
	else if(searchBST(avl_root, spath, strlen(spath)) == 1)
	{
		temp = Searchnarray(spath);
		if (strcmp(temp->nodefile_descriptor->file_type, "dir") == 0)
		{
			success = -1;
			printf("%s%s\n", "copyfile_FAILURE ", ERR_VFS_COPYFILE_03);
		}
	}

	return success;
}

int export_file_validate(char *spath, char *dpath)
{
	int success = 1;
	struct node* temp = NULL;
	
	if(strlen(spath) == 0 || strlen(dpath) == 0)
	{
		success = -1;
		printf("%s%s\n", "exportfile_FAILURE ", ERR_VFS_EXPORTFILE_00);
	}
	
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "exportfile_FAILURE ", ERR_VFS_EXPORTFILE_04);
	}
	else if(searchBST(avl_root, spath, strlen(spath)) == 0)
	{
		success = -1;
		printf("%s%s\n", "exportfile_FAILURE ", ERR_VFS_EXPORTFILE_01);

	}
	else if(searchBST(avl_root, spath, strlen(spath)) == 1)
	{
		temp = Searchnarray(spath);
		if (strcmp(temp->nodefile_descriptor->file_type, "dir") == 0)
		{
			success = -1;
			printf("%s%s\n", "exportfile_FAILURE ", ERR_VFS_EXPORTFILE_03);
		}
	}

	return success;
}

// cannot create file error?? NOT there in error list

int search_file_validate(char *name, char *path)
{
	int success = 1;
	struct node* temp = NULL;
	
	if(strlen(name) == 0 || strlen(path) == 0)
	{
		success = -1;
		printf("%s%s\n", "searchfile_FAILURE ", ERR_VFS_SEARCHFILE_00);
	}
	
	else if(vfs_mounted == 0)
	{
		success = -1;
		printf("%s%s\n", "exportfile_FAILURE ", ERR_VFS_SEARCHFILE_02);
	}

	return success;
}

// #################################################### sagar's code ends ########################################################

// ################################################### yogesh's code begins ######################################################

int add_file_validate(char *vfspathv, char *namev, char *filepathv)
{
	int success = 1;
	char temp[100];
	temp[0] = '\0';
	FILE *ptr;
	makeBSTpath(temp, vfspathv, namev);
//	printf("\n%s\n", temp);
	if(strlen(vfspathv) == 0 || strlen(namev) == 0 || strlen(filepathv) == 0)
	{
	success = -1;
	printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_00);
	}
	else if(vfs_mounted == 0)
	{
	success = -1;
	printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_07);
	}
	else if(checkslash(namev) == -1)
	{
	success = -1;
	printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_02);
	}
	else if(searchBST(avl_root, vfspathv, strlen(vfspathv)) == 0)
	{
		success = -1;
		printf("%s%s\n", "addfile_FAILURE ", "Misc. error occurred");
	}

	else if(searchBST(avl_root, temp, strlen(temp)) == 1)
	{
	success = -1;
	printf("%s%s\n", "addfile_FAILURE ", ERR_VFS_ADDFILE_03);
	}
	else if ((ptr = fopen(filepathv,"rb")) == NULL)
	{
		success = -1;
		printf("%s%s\n", "addfile_FAILURE ", "cannot find source file");
	}
	return success;
}

int list_file_validate(char *vfspathv, char *filepathv)
{
	int success = 1,i=0,j=0;
	char namev[20],ext[10];
	struct node* temp;

	//makeBSTpath(temp, vfspathv, namev);

	if(strlen(vfspathv) == 0 || strlen(filepathv) == 0)
	{
	success = -1;
	printf("%s%s\n", "listfile_FAILURE ", ERR_VFS_LISTFILE_00);
	return success;
	}
	else if(vfs_mounted == 0)
	{
	success = -1;
	printf("%s%s\n", "listfile_FAILURE ", ERR_VFS_LISTFILE_04);
	return success;
	}

	else if(searchBST(avl_root, vfspathv, strlen(vfspathv)) == 0)
	{
	success = -1;
	printf("%s%s\n", "listfile_FAILURE ", ERR_VFS_LISTFILE_01);
	return success;
	}
	// else if(strcmp(ext,"txt") != 0 )
	// {
	// success = -1;
	// printf("%s%s\n", "listfile_FAILURE ", ERR_VFS_LISTFILE_02);
	// return success;
	// }

	if (searchBST(avl_root, vfspathv, strlen(vfspathv)) == 1 && vfs_mounted==1)
	{
		temp = Searchnarray(vfspathv);
		strcpy(namev,temp->nodefile_descriptor->file_name);
		i = strlen(namev)-1;
		while(namev[i] != '.')
		{
			if(i == 0)
			break;
			i--;
		}
		i++;
		while(i<=strlen(namev)-1)
		{
			ext[j] = namev[i];
			j++;
			i++;
		}
		ext[j] == '\0';
		if(strcmp(ext,"txt") != 0 )
		{
			success = -1;
			printf("%s%s\n", "listfile_FAILURE ", ERR_VFS_LISTFILE_02);
			return success;
		}
	}
	return success;
}

int list_dir_validate(char *vfspathv, int flagv ,char *filepathv)
{
	int success = 1;
	char temp[100];
	temp[0] = '\0';

	//makeBSTpath(temp, pathv, namev);
	if(strlen(vfspathv) == 0 || strlen(filepathv) == 0)
	{
	success = -1;
	printf("%s%s\n", "listdir_FAILURE ", ERR_VFS_LISTDIR_00);
	}
	else if(vfs_mounted == 0)
	{
	success = -1;
	printf("%s%s\n", "listdir_FAILURE ", ERR_VFS_LISTDIR_03);
	}
	else if(searchBST(avl_root, vfspathv, strlen(vfspathv)) == 0)
	{
	success = -1;
	printf("%s%s\n", "listdir_FAILURE ", ERR_VFS_LISTDIR_01);

	}

	else if (flagv <0 || flagv >1)
	{
	success = -1;
	printf("%s%s\n", "listdir_FAILURE ", ERR_VFS_LISTDIR_02);
	}


	return success;
}

// ################################################## yogesh's code ends #########################################################

// ################################################# tushar's code begins ########################################################

int remove_file_validate(char *pathv)
{
	int success=1;
	if(strlen(pathv) == 0)
	{
	success = -1;
	printf("%s%s\n", "Removefile_FAILURE ", ERR_VFS_REMOVEFILE_00);
	}

	else if(vfs_mounted == 0)
	{
	success = -1;
	printf("%s%s\n", "Removefile_FAILURE ", ERR_VFS_REMOVEFILE_02);
	}
	else if(searchBST(avl_root, pathv, strlen(pathv)) == 0)
	{
	success = -1;
	printf("%s%s\n", "Removefile_FAILURE ", ERR_VFS_REMOVEFILE_01);

	}
	return success;

}

int move_file_validate(char* sourcev,char* destv, char* name)
{
	char tempp[100];
	tempp[0] = '\0';
	makeBSTpath(tempp, destv, name);
	int success=1;
	if((strlen(sourcev) == 0) || (strlen(destv) == 0))
	{
	success = -1;
	printf("%s%s\n", "Movefile_FAILURE ", ERR_VFS_MOVEFILE_00);
	return success;
	}

	else if(vfs_mounted == 0)
	{
	success = -1;
	printf("%s%s\n", "Movefile_FAILURE ", ERR_VFS_MOVEFILE_06);
	return success;
	}
	else if(searchBST(avl_root, sourcev, strlen(sourcev)) == 0)
	{
	success = -1;
	printf("%s%s\n", "Movefile_FAILURE ", ERR_VFS_MOVEFILE_01);
	return success;

	}
	else if(searchBST(avl_root, destv, strlen(destv)) == 0)
	{
	success = -1;
	printf("%s%s\n", "Movefile_FAILURE ", ERR_VFS_MOVEFILE_02);
	return success;
	}
	else if(searchBST(avl_root, tempp, strlen(tempp)) == 1)
	{
	success = -1;
	printf("%s%s\n", "Movefile_FAILURE ", "File with same name already exists");
	return success;
	}
	return success;
}

int update_file_validate(char* sourcev, char* dirfilepath)
{
	int success=1, flag=1;
	FILE *ptr;
	ptr=fopen(dirfilepath,"r");
	if(ptr==NULL)
	flag=0;
	else
	fclose(ptr);     //glibc
	if((strlen(sourcev) == 0) || (strlen(dirfilepath) == 0))
	{
	success = -1;
	printf("%s%s\n", "Updatefile_FAILURE ", ERR_VFS_UPDATEFILE_00);
	return success;
	}
	else if(vfs_mounted == 0)
	{
	success = -1;
	printf("%s%s\n", "Updatefile_FAILURE ", ERR_VFS_UPDATEFILE_04);
	return success;
	}
	else if(searchBST(avl_root, sourcev, strlen(sourcev)) == 0)
	{
	success = -1;
	printf("%s%s\n", "Updatefile_FAILURE ", ERR_VFS_UPDATEFILE_01);
	return success;

	}
	else if(flag==0)
	{
	success = -1;
	printf("%s%s\n", "Updatefile_FAILURE ", ERR_VFS_UPDATEFILE_02);
	return success;
	}
	return success;
}


// ############################################### tushar's code ends #############################################################

void makeBSTpath(char *temp, char *pathv, char *namev)
{
	if(strlen(pathv) == 1)
	{
		strcat(temp, pathv);
		strcat(temp, namev);
	}

	else
	{
		strcat(temp, pathv);
		strcat(temp, "/");
		strcat(temp, namev);
	}
}


int checkslash(char *name)

{
	int checkval=1;
	while(*name!='\0')
	{
		if(*name == '/')
		{
			checkval=-1;
			break;
		}
		name++;
	}

	return checkval;
}

